package com.hxzy.aspect;

import com.alibaba.fastjson.JSON;
import com.hxzy.mapper.OperateLogMapper;
import com.hxzy.pojo.OperateLog;
import com.hxzy.utils.JwtUtils;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @author wzm
 * @create 2023-10-17 10:41
 * project_name:stu_sys
 */
@Component
@Slf4j
@Aspect
public class OperacteLogAspect {
    //从SpringIOC容器中获取request对象
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Around("@annotation(com.hxzy.anno.OperateLog)")
    public Object Logs(ProceedingJoinPoint joinPoint) throws Throwable {
        //操作人、操作时间、执行方法的全类名、执行方法名、方法运行时参数、返回值、方法执行时长
        //操作人ID-当前登录人ID
        //登录数据在jwt中 前端每次传过来的
        String token = request.getHeader("token");
        //解析jwt得到登录用户信息
        Integer operateUser = (Integer) JwtUtils.parserJwt(token).get("id");

        //操作的时间
        LocalDateTime operateTime = LocalDateTime.now();

        //操作类名
        String className = joinPoint.getTarget().getClass().getName();

        //操作方法名
        String methodName = joinPoint.getSignature().getName();

        //操作参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

        //执行方法前记录时间
        long begin = System.currentTimeMillis();

        //运行目标方法
        Object result = joinPoint.proceed();

        //方法执行后
        long end = System.currentTimeMillis();

        //返回值
        String returnValue = JSON.toJSONString(result);//fastjson将java-字符串

        //执行时长
        long costTime = end - begin;

        //将全部信息添加到数据库中
        OperateLog operateLog = new OperateLog(null,operateUser,operateTime,className,methodName,methodParams,returnValue,costTime);
        log.info("日志对象：{}",operateLog);
        operateLogMapper.insertLog(operateLog);

        return result;
    }
}
